#include <iostream>
#include <httplib.h>
#include <brpc/channel.h>
#include <log.h>
#include <memory>
#include <gflags/gflags.h>
#include <odb/mysql/database.hxx>
#include <gtest/gtest.h>
#include "etcd_path.h"

#include "brpc.h"
// #include "storage.pb.h"
#include "problem/problem.h"
#include "user.pb.h"
#include "user/user.h"
#include "blog/blog.h"
#include "home/home.h"

DEFINE_string(etcd_path, "127.0.0.1:2379", "etcd addr");
DEFINE_int32(start_port, 38080, "start port");

DEFINE_string(mysql_user,"lyt", "链接数据库的用户");
DEFINE_string(mysql_passwd,"001216", "链接数据库的密码");
DEFINE_string(mysql_db,"OJ", "要连接的数据库名称");
DEFINE_string(mysql_host,"43.143.245.137", "链接数据库的IP地址");
DEFINE_int32(mysql_port,33306, "链接数据库的端口");
DEFINE_string(mysql_charset,"utf8", "链接数据库的字符集");
DEFINE_int32(mysql_conn_pool,5, "链接数据库的连接池大小");

using namespace std;


// 辅助函数：读取文件内容
std::string read_file(const std::string& path) {
    std::ifstream ifs(path, std::ios::in | std::ios::binary);
    if (!ifs) return "";
    std::string content((std::istreambuf_iterator<char>(ifs)),
                         std::istreambuf_iterator<char>());
    return content;
}

int main(int argc, char **argv){
    // httplib::Server svr;
    // 向brpc注册一个etcd自定义得命名服务 
    lyt::EtcdNamingService name_server;
    brpc::NamingServiceExtension()->RegisterOrDie("etcd", &name_server);

    
    httplib::Server svr;
    svr.set_base_dir("/home/lyt/OnlineJudge/oj-frontend/dist");
    UserModule::ptr user = std::make_shared<UserModule>(FLAGS_etcd_path);
    BlogModule::ptr blog = std::make_shared<BlogModule>(FLAGS_etcd_path);
    ProblemModule::ptr problem = std::make_shared<ProblemModule>(FLAGS_etcd_path);
    HomeModule::ptr home = std::make_shared<HomeModule>(FLAGS_etcd_path);
    // =======================================user=========================================
    svr.Post("/user/send-code",[&user](const httplib::Request& req,httplib::Response& res){
        user->userSendCode(req, res);
    });
    svr.Post("/user/register",[&user](const httplib::Request& req,httplib::Response& res){
        user->userRegister(req, res);
    });
    svr.Post("/user/login",[&user](const httplib::Request& req,httplib::Response& res){
        user->userLogin(req, res);
    });
    svr.Post("/user/code-login",[&user](const httplib::Request& req,httplib::Response& res){
        user->userCodeLogin(req, res);
    });
    svr.Post("/user/stats",[&user](const httplib::Request& req,httplib::Response& res){
        user->getUserstats(req, res);
    });
    svr.Post("/user/profile",[&user](const httplib::Request& req,httplib::Response& res){
        user->getUserstatssummary(req, res);
    });
    svr.Post("/user/logout",[&user](const httplib::Request& req,httplib::Response& res){
        user->userLogout(req, res);
    });
    svr.Post("/user/update-username",[&user](const httplib::Request& req,httplib::Response& res){
        user->updateUsername(req, res);
    });
    svr.Post("/user/update-avatar",[&user](const httplib::Request& req,httplib::Response& res){
        debuglog << "/user/update-avatar";
        user->updateuserAvatar(req, res);
    });
    svr.Post("/user/change-password",[&user](const httplib::Request& req,httplib::Response& res){
        user->updateuserPassword(req, res);
    });
    svr.Post("/user/change-password-by-email",[&user](const httplib::Request& req,httplib::Response& res){
        user->updateuserPasswordbyemail(req, res);
    });
    svr.Post("/user/get-follow-status",[&user](const httplib::Request& req,httplib::Response& res){
        user->getFllowstats(req, res);
    });
    svr.Post("/user/follow",[&user](const httplib::Request& req,httplib::Response& res){
        user->Follow(req, res);
    });
    svr.Post("/user/unfollow",[&user](const httplib::Request& req,httplib::Response& res){
        user->UnFollow(req, res);
    });
    svr.Post("/user/get-user-info",[&user](const httplib::Request& req,httplib::Response& res){
        user->getUserinfo(req, res);
    });
    svr.Post("/user/get-default-avatar",[&user](const httplib::Request& req,httplib::Response& res){
        user->getDefaultavatar(req, res);
    });
    // =======================================user-end=========================================

    // =======================================blog=========================================
    svr.Post("/blog/list",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogList(req, res);
    });
    svr.Post("/blog/detail",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogDetail(req, res);
    });
    svr.Post("/blog/like",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogLike(req, res);
    });
    svr.Post("/blog/submitcomment",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogComment(req, res);
    });
    svr.Post("/blog/getcomments",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogGetcomment(req, res);
    });
    svr.Post("/blog/delete",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogDelete(req, res);
    });
    svr.Post("/blog/create",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogCreate(req, res);
    });
    svr.Post("/blog/edit",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogEdit(req, res);
    });
    svr.Post("/blog/likedblogs",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogLikelist(req, res);
    });
    svr.Post("/blog/deletelike",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogLikedelete(req, res);
    });
    svr.Post("/blog/userblogs",[&blog](const httplib::Request& req,httplib::Response& res){
        blog->blogUser(req, res);
    });
    // =======================================blog-end=========================================

    // =======================================problem=========================================
    svr.Post("/problem/list",[&problem](const httplib::Request& req,httplib::Response& res){
        problem->problemList(req, res);
    });
    svr.Post("/problem/detail",[&problem](const httplib::Request& req,httplib::Response& res){
        problem->problemDetail(req, res);
    });
    svr.Post("/problem/submit",[&problem](const httplib::Request& req,httplib::Response& res){
        problem->problemSubmit(req, res);
    });
    svr.Post("/problem/submissionlist",[&problem](const httplib::Request& req,httplib::Response& res){
        problem->problemSubmissiondetail(req, res);
    });
    svr.Post("/problem/submissiondetail",[&problem](const httplib::Request& req,httplib::Response& res){
        problem->problemSubmissionlist(req, res);
    });
    svr.Post("/user/problems",[&problem](const httplib::Request& req,httplib::Response& res){
        problem->problemUserproblemlist(req, res);
    });
    // =======================================problem-end=========================================

    // =======================================home=========================================
    svr.Get("/home/data",[&home](const httplib::Request& req,httplib::Response& res){
        // 行为分析模块
        home->UserBehaviorAnalysis(req,res);
    });
    svr.Post("/home/search",[&home](const httplib::Request& req,httplib::Response& res){
        home->homeSearch(req, res);
    });
    
    
    // =======================================home-end=========================================


    // catch-all fallback：非静态文件的路径，返回 index.html
    svr.set_error_handler([](const httplib::Request &req, httplib::Response &res) {
        // 只对 404 做处理
        std::string content = read_file("/home/lyt/OnlineJudge/oj-frontend/dist/index.html");
        if (!content.empty()) {
            res.set_content(content, "text/html");
            res.status = 200;
        } else {
            res.set_content("index.html not found", "text/plain");
            res.status = 500;
        }
    });
    
    svr.listen("0.0.0.0", FLAGS_start_port);

    return 0;
}